package edu.columbia.plt.visage.editor;

/* 
 * VisageEditor - modification of NutPad editor
 */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


import edu.columbia.plt.visage.parser.ParseException;
import edu.columbia.plt.visage.parser.VisageParser;

import java.io.*;

///////////////////////////////////////////////////////////////////////// NutPad
public class VisageEditor extends JFrame {
 //... Components 
 private JTextArea    _editArea;
 private JFileChooser _fileChooser = new JFileChooser();
 
 //... Create actions for menu items, buttons, ...
 private Action _openAction = new OpenAction();
 private Action _saveAction = new SaveAction();
 private Action _runAction =  new RunAction();
 private Action _exitAction = new ExitAction(); 
 private VisageParser parser;

 //===================================================================== main
 public static void main(String[] args) {
     new VisageEditor();
 }
 
 //============================================================== constructor
 public VisageEditor() {
     //... Create scrollable text area.
	 
	 _fileChooser.setFileFilter(new VisageFileFilter());
     _editArea = new JTextArea(15, 80);
     _editArea.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
     _editArea.setFont(new Font("monospaced", Font.PLAIN, 14));
     JScrollPane scrollingText = new JScrollPane(_editArea);
     
     //-- Create a content pane, set layout, add component.
     JPanel content = new JPanel();
     content.setLayout(new BorderLayout());
     content.add(scrollingText, BorderLayout.CENTER);
     
     //... Create menubar
     JMenuBar menuBar = new JMenuBar();
     JMenu fileMenu = menuBar.add(new JMenu("File"));
     fileMenu.setMnemonic('F');
     fileMenu.add(_openAction);       // Note use of actions, not text.
     fileMenu.add(_saveAction);
     fileMenu.addSeparator();
     fileMenu.add(_runAction);
     fileMenu.addSeparator();
     fileMenu.add(_exitAction);
     
     //... Set window content and menu.
     setContentPane(content);
     setJMenuBar(menuBar);
     
     //... Set other window characteristics.
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     setTitle("Visage Editor");
     pack();
     setLocationRelativeTo(null);
     setVisible(true);
 }
 
 ////////////////////////////////////////////////// inner class OpenAction
 class OpenAction extends AbstractAction {
     //============================================= constructor
     public OpenAction() {
         super("Open...");
         putValue(MNEMONIC_KEY, new Integer('O'));
     }
     
     //========================================= actionPerformed
     public void actionPerformed(ActionEvent e) {
    	 
         int retval = _fileChooser.showOpenDialog(VisageEditor.this);
         if (retval == JFileChooser.APPROVE_OPTION) {
             File f = _fileChooser.getSelectedFile();
             try {
                 FileReader reader = new FileReader(f);
                 _editArea.read(reader, "");  // Use TextComponent read
             } catch (IOException ioex) {
                 System.out.println(e);
                 System.exit(1);
             }
         }
     }
 }
 
 //////////////////////////////////////////////////// inner class SaveAction
 class SaveAction extends AbstractAction {
     //============================================= constructor
     SaveAction() {
         super("Save...");
         putValue(MNEMONIC_KEY, new Integer('S'));
     }
     
     //========================================= actionPerformed
     public void actionPerformed(ActionEvent e) {
         int retval = _fileChooser.showSaveDialog(VisageEditor.this);
         if (retval == JFileChooser.APPROVE_OPTION) {
             File f = _fileChooser.getSelectedFile();
             try {
            	 if ( !f.toString().contains(".vis") ) {
            		 f = new File(f.toString()+".vis");
            	 }
                 FileWriter writer = new FileWriter(f);
                 _editArea.write(writer);  // Use TextComponent write
             } catch (IOException ioex) {
                 JOptionPane.showMessageDialog(VisageEditor.this, ioex);
                 System.exit(1);
             }
         }
     }
 }
 //////////////////////////////////////////////////// inner class SaveAction
 class RunAction extends AbstractAction {
     //============================================= constructor
	 RunAction() {
         super("Run");
         putValue(MNEMONIC_KEY, new Integer('R'));
     }
     
     //========================================= actionPerformed
     public void actionPerformed(ActionEvent e) {
    
    	 
		StringWriter sw = new StringWriter();
		
		try {
			_editArea.write(sw);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			return;
		} // Use TextComponent write
		
		if ( parser == null ) {
			parser = new VisageParser(new StringReader(sw.toString()));
		}
		else {
			parser.ReInit(new StringReader(sw.toString()));
		}
		
		try {
			parser.program();
		} catch (ParseException e1) {
			// TODO Auto-generated catch block
			JOptionPane.showMessageDialog(_editArea, "Parsing error: " + e1.getMessage());
			return;
		}
			
	     String s = null;

         try {
             
 	    // run the Unix "ps -ef" command
             // using the Runtime exec method:
             Process p = Runtime.getRuntime().exec("javac -sourcepath src/ -classpath lib/jcommon-1.0.16.jar  -d build/classes src/edu/columbia/plt/visage/App.java");
             
             BufferedReader stdInput = new BufferedReader(new 
                  InputStreamReader(p.getInputStream()));

             BufferedReader stdError = new BufferedReader(new 
                  InputStreamReader(p.getErrorStream()));

             // read the output from the command
             System.out.println("Here is the standard output of the command:\n");
             while ((s = stdInput.readLine()) != null) {
                 System.out.println(s);
             }
             

             String error = "";
             while ((s = stdError.readLine()) != null) {
            	 error += s + "\n";
             }
             if ( !error.equals("") ) {
            	 JOptionPane.showMessageDialog(_editArea, "Got an error during compilation: " + error);
            	 return;
             }
             
             
         }
         catch (IOException e2) {
        	 JOptionPane.showMessageDialog(_editArea, "Caught an exception during compiling: " + e2.getMessage());
             return;
         }
         
         
         try {
             
      	    // run the Unix "ps -ef" command
		  // using the Runtime exec method:
		  Process p = Runtime.getRuntime().exec("java -cp build/classes edu.columbia.plt.visage.App");
		  
		  BufferedReader stdInput = new BufferedReader(new 
		       InputStreamReader(p.getInputStream()));
		
		  BufferedReader stdError = new BufferedReader(new 
		       InputStreamReader(p.getErrorStream()));
		
		  // read the output from the command
		  System.out.println("Here is the standard output of the command:\n");
		  while ((s = stdInput.readLine()) != null) {
		      System.out.println(s);
		  }
		  
          String error = "";
          while ((s = stdError.readLine()) != null) {
         	 error += s + "\n";
          }
          if ( !error.equals("") ) {
         	 JOptionPane.showMessageDialog(_editArea, "Got an error while trying to run compiled code: " + error);
         	 return;
          }
          
		      
		  }
		  catch (IOException e2) {
			  JOptionPane.showMessageDialog(_editArea, "Caught an exception while trying to run the compiled code: " + e2.getMessage());
			  return;
		  }
		
     }
 }
 ///////////////////////////////////////////////////// inner class ExitAction
 class ExitAction extends AbstractAction {
     
     //============================================= constructor
     public ExitAction() {
         super("Exit");
         putValue(MNEMONIC_KEY, new Integer('X'));
     }
     
     //========================================= actionPerformed
     public void actionPerformed(ActionEvent e) {
         System.exit(0);
     }
 }
}